共计 2207 个字符,预计需要花费 6 分钟才能阅读完成。
前言
同一基类的不同导出类,对同一方法的调用,其运行结果不同,这样就可以消除类型之间的耦合关系,也是多态的作用;
那么多态也称动态绑定、后期绑定或运行时绑定!
向上转型
把对某个对象的引用视为对其父类类型的引用,这种做法称为向上转型;
/**
* @author plm
* @create 2021/3/7 19:58
*/
public enum Note {
MIDDLE_C,
C_SHARP,
B_FLAT
}
/**
* @author plm
* @create 2021/3/7 19:59
*/
class Instrument {
public void play(Note n) {
System.out.println("Instrument.play()");
}
}
class Wind extends Instrument {
public void play(Note n) {
System.out.println("Wind.play(" + n + ")");
}
}
class Stringed extends Instrument {
public void play(Note n) {
System.out.println("Stringed.play(" + n + ")");
}
}
class Brass extends Instrument {
public void play(Note n) {
System.out.println("Brass.play(" + n + ")");
}
}
public class Music {
public static void tune(Instrument i) {
i.play(Note.B_FLAT);
}
public static void main(String[] args) {
Wind wind = new Wind();
Stringed stringed = new Stringed();
Brass brass = new Brass();
tune(wind);
tune(stringed);
tune(brass);
}
}
/* 输出
Wind.play(B_FLAT)
Stringed.play(B_FLAT)
Brass.play(B_FLAT)
*/
仅接收父类作为参数,编写的方法至于基类打交道;
绑定
将一个方法调用同一个方法主体关联起来,这个被称为绑定,又分为前期绑定和后期绑定;
前期绑定就是在程序执行前进行绑定(一般由编译器和连接程序去实现);
后期绑定就是在运行时根据对象的类型进行绑定(又可称为动态绑定或者运行时绑定);
如何切换这两种绑定呢?
Java中除了 static
方法、final
方法(private
方法属于final
方法)之外,其他方法都是动态绑定!
Tips:
1.不要试图去重写基类得私有方法;
2.成员变量和静态方法并不具备多态性;
协议返回类型
JDK 1.5中添加了 协议返回类型,子类重写父类的方法时子类中方法返回值类型
与父类中方法返回值类型
,两者可以一致也可以前者是后者的子类;
/**
* @author plm
* @create 2021/3/7 20:37
*/
class Grain {
@Override
public String toString() {
return "Grain{}";
}
}
class Wheat extends Grain {
@Override
public String toString() {
return "Wheat{}";
}
}
class Mill {
Grain process() {
return new Grain();
}
}
class WheatMill extends Mill {
Wheat process() {
return new Wheat();
}
}
public class CoverReturn {
public static void main(String[] args) {
Mill mill = new Mill();
Grain process = mill.process();
System.out.println(process);
mill = new WheatMill();
process = mill.process();
System.out.println(process);
}
}
/* 输出
Grain{}
Wheat{}
*/
向下转型
因为 向上转型(在继承关系中向父类变型)会丢失具体子类自己的类型信息,那么我们可以向下转型,这就可以获取到子类独有的类型信息;
/**
* @author plm
* @create 2021/3/7 20:50
*/
class Tep {
private int i;
public void f() {
}
}
class NewTep extends Tep {
private int j;
public void j() {
}
}
public class RTTI {
public static void main(String[] args) {
Tep[] teps = {
new Tep(), new NewTep()
};
//! NewTep tep = (NewTep) teps[0]; // java.lang.ClassCastException
NewTep tep1 = (NewTep) teps[1];
}
}
在运行期间对类型进行检查的行为我们称为“ 运行时类型识别”(RTTI
);如果遇到转型错误就会抛出异常: java.lang.ClassCastException!
最后
多态意味着“不同的形式
”,从基类继承而来相同的接口, 不同导出类对同一个接口的不同使用形式不同导出类对该接口的不同使用形式:不同版本的动态绑定;
正文完